package uba.algo3.tp2.ej1final;

import static org.junit.Assert.*;
import java.util.ArrayList;
import org.junit.Test;

public class PriorityQueueExtTest {
	
	PriorityQueueExt<Ciudad> p;
	Ciudad c;

	@Test
	public void testEncolarDesencolar(){
		
		p = new PriorityQueueExt<Ciudad>();
		encolarCiudades(); //pongo 8 ciudades con pesos 1,1,2,3,3,4,5,6
		Ciudad max = p.getMax();
		assertEquals("Ciudad6",max.getNombre());
		max = p.getMax();
		assertEquals("Ciudad5",max.getNombre());
		max = p.getMax();
		assertEquals("Ciudad4",max.getNombre());
		max = p.getMax();
		assertTrue("Ciudad3a".equals(max.getNombre()) || "Ciudad3b".equals(max.getNombre()));
		max = p.getMax();
		assertTrue("Ciudad3a".equals(max.getNombre()) || "Ciudad3b".equals(max.getNombre()));
		max = p.getMax();
		assertEquals("Ciudad2",max.getNombre());
		max = p.getMax();
		assertTrue("Ciudad1a".equals(max.getNombre()) || "Ciudad1b".equals(max.getNombre()));
		max = p.getMax();
		assertTrue("Ciudad1a".equals(max.getNombre()) || "Ciudad1b".equals(max.getNombre())); 
		assertTrue(p.isEmpty()); //ya no quedan mas elementos por desencolar
		
	}
	
	@Test
	public void testReubicar(){
		p = new PriorityQueueExt<Ciudad>();
		Ciudad c1 = new Ciudad("c1");
		Ciudad c2 = new Ciudad("c2");
		Ciudad c3 = new Ciudad("c3");
		Ciudad c4 = new Ciudad("c4");
		Ciudad c5 = new Ciudad("c5");
		
		c1.setPeso(1);
		c2.setPeso(2);
		c3.setPeso(3);
		c4.setPeso(4);
		c5.setPeso(5);
		
		p.encolar(c3);
		p.encolar(c5);
		p.encolar(c2);
		p.encolar(c1);
		p.encolar(c4);
		
		c2.setPeso(6); 
		p.reubicar(c2); //le cambie el peso de c2 a 6, y ahora deberia ser el proximo a ser desencolado
		assertEquals(c2.getNombre(),((Ciudad) (p.verMax())).getNombre());
		
		c1.setPeso(5); 
		p.reubicar(c1); //ahora c1 se deberia haber intercambiado con c4 en el heap
		p.getMax(); //desencolamos c2, ahora c1 esta en la raiz del heap
		assertEquals(c1.getNombre(),((Ciudad) (p.verMax())).getNombre());
		
		c4.setPeso(5); 
		p.reubicar(c4); //si bien c4 ahora tiene peso 5, no hay necesidad de reestablecer el invariante
		//comprobamos que c4, que era el 2do elemento mas prioritario antes de ponerle un nuevo peso,
		//sigue siendo 2do
		assertEquals(c1.getNombre(),((Ciudad) (p.verMax())).getNombre());
		
		//desencolamos 3 veces y comprobamos que c3 es el proximo a ser desencolado
		p.getMax();
		p.getMax();
		p.getMax();
		assertEquals(c3.getNombre(),((Ciudad) (p.verMax())).getNombre());
		
		//cambiamos la prioridad a un unico elemento de la cola y vemos que sigue siendo el proximo
		//a desencolar
		c3.setPeso(1000);
		assertEquals(c3.getNombre(),((Ciudad) (p.verMax())).getNombre());
	
	}
	
	private void encolarCiudades(){
		Ciudad c; 
		c = new Ciudad("Ciudad2");
		c.setPeso(2);
		p.encolar(c);
		c = new Ciudad("Ciudad5");
		c.setPeso(5);
		p.encolar(c);
		c = new Ciudad("Ciudad1a");
		c.setPeso(1);
		p.encolar(c);
		c = new Ciudad("Ciudad3a");
		c.setPeso(3);
		p.encolar(c);
		c = new Ciudad("Ciudad6"); 
		c.setPeso(6);
		p.encolar(c);
		c = new Ciudad("Ciudad1b");
		c.setPeso(1);
		p.encolar(c);
		c = new Ciudad("Ciudad3b");
		c.setPeso(3);
		p.encolar(c);
		c = new Ciudad("Ciudad4"); 
		c.setPeso(4);
		p.encolar(c);
	}
	
	
	
	
}
